/////////////////////////////////////////////////////////////////////////////
// Name:        commandeditordialog.cpp
// Purpose:     
// Author:      Julian Smart
// Modified by: 
// Created:     22/11/2008 13:43:50
// RCS-ID:      
// Copyright:   (c) Anthemion Software Limited
// Licence:     New BSD License
/////////////////////////////////////////////////////////////////////////////

#include "wx/wx.h"

////@begin includes
////@end includes

#include "wx/valgen.h"
#include "uiutils/uicustomization.h"
#include "commandeditor/commandeditordialog.h"

////@begin XPM images
////@end XPM images

bool wxCommandEditorDialog::sm_useTooltips = true;
int  wxCommandEditorDialog::sm_helpId = 0;

wxUICustomization* wxCommandEditorDialog::sm_uiCustomization = NULL;

/*
 * wxCommandEditorDialog type definition
 */

IMPLEMENT_DYNAMIC_CLASS( wxCommandEditorDialog, wxScrollingDialog )


/*
 * wxCommandEditorDialog event table definition
 */

BEGIN_EVENT_TABLE( wxCommandEditorDialog, wxScrollingDialog )

////@begin wxCommandEditorDialog event table entries
    EVT_LISTBOX( ID_COMMANDEDITORDIALOG_COMMANDS, wxCommandEditorDialog::OnCommandeditordialogCommandsSelected )

    EVT_BUTTON( ID_COMMANDEDITORDIALOG_ADD, wxCommandEditorDialog::OnCommandeditordialogAddClick )

    EVT_BUTTON( ID_COMMANDEDITORDIALOG_DELETE, wxCommandEditorDialog::OnCommandeditordialogDeleteClick )
    EVT_UPDATE_UI( ID_COMMANDEDITORDIALOG_DELETE, wxCommandEditorDialog::OnCommandeditordialogDeleteUpdate )

    EVT_BUTTON( ID_COMMANDEDITORDIALOG_RENAME, wxCommandEditorDialog::OnCommandeditordialogRenameClick )
    EVT_UPDATE_UI( ID_COMMANDEDITORDIALOG_RENAME, wxCommandEditorDialog::OnCommandeditordialogRenameUpdate )

    EVT_UPDATE_UI( ID_COMMANDEDITORDIALOG_NAME, wxCommandEditorDialog::OnCommandeditordialogNameUpdate )

    EVT_UPDATE_UI( ID_COMMANDEDITORDIALOG_COMMAND, wxCommandEditorDialog::OnCommandeditordialogCommandUpdate )

    EVT_BUTTON( ID_COMMANDEDITORDIALOG_BROWSE, wxCommandEditorDialog::OnCommandeditordialogBrowseClick )
    EVT_UPDATE_UI( ID_COMMANDEDITORDIALOG_BROWSE, wxCommandEditorDialog::OnCommandeditordialogBrowseUpdate )

    EVT_UPDATE_UI( ID_COMMANDEDITORDIALOG_SHOWTHIS, wxCommandEditorDialog::OnCommandeditordialogShowthisUpdate )

    EVT_BUTTON( wxID_HELP, wxCommandEditorDialog::OnHelpClick )
    EVT_UPDATE_UI( wxID_HELP, wxCommandEditorDialog::OnHelpUpdate )

////@end wxCommandEditorDialog event table entries

END_EVENT_TABLE()


/*
 * wxCommandEditorDialog constructors
 */

wxCommandEditorDialog::wxCommandEditorDialog()
{
    Init();
}

wxCommandEditorDialog::wxCommandEditorDialog( const wxEditorCommandArray& cmds, const wxString& msg, wxWindow* parent, wxWindowID id, const wxString& caption, const wxPoint& pos, const wxSize& size, long style )
{
    Init();
    Create(cmds, msg, parent, id, caption, pos, size, style);
}


/*
 * ebCommandEditorDialog creator
 */

bool wxCommandEditorDialog::Create( const wxEditorCommandArray& cmds, const wxString& msg, wxWindow* parent, wxWindowID id, const wxString& caption, const wxPoint& pos, const wxSize& size, long style )
{
    m_commands = cmds;
    m_caption = msg;
    
////@begin wxCommandEditorDialog creation
    SetExtraStyle(wxWS_EX_BLOCK_EVENTS);
    wxScrollingDialog::Create( parent, id, caption, pos, size, style );

    CreateControls();
    if (GetSizer())
    {
        GetSizer()->SetSizeHints(this);
    }
    Centre();
////@end wxCommandEditorDialog creation
    return true;
}


/*
 * wxCommandEditorDialog destructor
 */

wxCommandEditorDialog::~wxCommandEditorDialog()
{
////@begin wxCommandEditorDialog destruction
////@end wxCommandEditorDialog destruction
}


/*
 * Member initialisation
 */

void wxCommandEditorDialog::Init()
{
////@begin wxCommandEditorDialog member initialisation
    m_captionCtrl = NULL;
    m_commandsCtrl = NULL;
    m_nameCtrl = NULL;
    m_commandCtrl = NULL;
    m_showThisCommandCtrl = NULL;
////@end wxCommandEditorDialog member initialisation
}


/*
 * Control creation for ebCommandEditorDialog
 */

void wxCommandEditorDialog::CreateControls()
{    
#ifdef __WXMAC__
    SetWindowVariant(wxWINDOW_VARIANT_SMALL);
#endif

////@begin wxCommandEditorDialog content construction
    wxCommandEditorDialog* itemScrollingDialog1 = this;

    wxBoxSizer* itemBoxSizer2 = new wxBoxSizer(wxVERTICAL);
    itemScrollingDialog1->SetSizer(itemBoxSizer2);

    wxBoxSizer* itemBoxSizer3 = new wxBoxSizer(wxVERTICAL);
    itemBoxSizer2->Add(itemBoxSizer3, 1, wxGROW|wxALL, 5);

    m_captionCtrl = new wxStaticText( itemScrollingDialog1, wxID_STATIC, _("Editing commands for XXX"), wxDefaultPosition, wxDefaultSize, 0 );
    itemBoxSizer3->Add(m_captionCtrl, 0, wxALIGN_LEFT|wxLEFT|wxRIGHT|wxTOP, 5);

    wxBoxSizer* itemBoxSizer5 = new wxBoxSizer(wxHORIZONTAL);
    itemBoxSizer3->Add(itemBoxSizer5, 1, wxGROW, 5);

    wxArrayString m_commandsCtrlStrings;
    m_commandsCtrl = new wxListBox( itemScrollingDialog1, ID_COMMANDEDITORDIALOG_COMMANDS, wxDefaultPosition, wxSize(-1, 120), m_commandsCtrlStrings, wxLB_SINGLE );
    m_commandsCtrl->SetHelpText(_("Available commands for this file type and role (editing or viewing)."));
    if (wxCommandEditorDialog::ShowToolTips())
        m_commandsCtrl->SetToolTip(_("Available commands for this file type and role (editing or viewing)."));
    itemBoxSizer5->Add(m_commandsCtrl, 1, wxGROW|wxALL, 5);

    wxBoxSizer* itemBoxSizer7 = new wxBoxSizer(wxVERTICAL);
    itemBoxSizer5->Add(itemBoxSizer7, 0, wxGROW|wxTOP|wxBOTTOM, 5);

    wxButton* itemButton8 = new wxButton( itemScrollingDialog1, ID_COMMANDEDITORDIALOG_ADD, _("&Add"), wxDefaultPosition, wxDefaultSize, 0 );
    itemButton8->SetHelpText(_("Click to add a new command."));
    if (wxCommandEditorDialog::ShowToolTips())
        itemButton8->SetToolTip(_("Click to add a new command."));
    itemBoxSizer7->Add(itemButton8, 0, wxALIGN_CENTER_HORIZONTAL|wxLEFT|wxRIGHT|wxBOTTOM, 5);

    wxButton* itemButton9 = new wxButton( itemScrollingDialog1, ID_COMMANDEDITORDIALOG_DELETE, _("&Delete"), wxDefaultPosition, wxDefaultSize, 0 );
    itemButton9->SetHelpText(_("Click to delete a command."));
    if (wxCommandEditorDialog::ShowToolTips())
        itemButton9->SetToolTip(_("Click to delete a command."));
    itemBoxSizer7->Add(itemButton9, 0, wxALIGN_CENTER_HORIZONTAL|wxLEFT|wxRIGHT|wxBOTTOM, 5);

    wxButton* itemButton10 = new wxButton( itemScrollingDialog1, ID_COMMANDEDITORDIALOG_RENAME, _("&Rename"), wxDefaultPosition, wxDefaultSize, 0 );
    itemButton10->SetHelpText(_("Click to rename the selected command."));
    if (wxCommandEditorDialog::ShowToolTips())
        itemButton10->SetToolTip(_("Click to rename the selected command."));
    itemBoxSizer7->Add(itemButton10, 0, wxALIGN_CENTER_HORIZONTAL|wxLEFT|wxRIGHT, 5);

    wxFlexGridSizer* itemFlexGridSizer11 = new wxFlexGridSizer(2, 2, 0, 0);
    itemFlexGridSizer11->AddGrowableCol(1);
    itemBoxSizer3->Add(itemFlexGridSizer11, 0, wxGROW|wxALL, 5);

    wxStaticText* itemStaticText12 = new wxStaticText( itemScrollingDialog1, wxID_STATIC, _("&Name:"), wxDefaultPosition, wxDefaultSize, 0 );
    itemFlexGridSizer11->Add(itemStaticText12, 0, wxALIGN_RIGHT|wxALIGN_CENTER_VERTICAL|wxALL, 5);

    m_nameCtrl = new wxTextCtrl( itemScrollingDialog1, ID_COMMANDEDITORDIALOG_NAME, _T(""), wxDefaultPosition, wxDefaultSize, wxTE_READONLY );
    m_nameCtrl->SetHelpText(_("A descriptive name for this command."));
    if (wxCommandEditorDialog::ShowToolTips())
        m_nameCtrl->SetToolTip(_("A descriptive name for this command."));
    itemFlexGridSizer11->Add(m_nameCtrl, 0, wxGROW|wxALIGN_CENTER_VERTICAL|wxALL, 5);

    wxStaticText* itemStaticText14 = new wxStaticText( itemScrollingDialog1, wxID_STATIC, _("C&ommand:"), wxDefaultPosition, wxDefaultSize, 0 );
    itemFlexGridSizer11->Add(itemStaticText14, 0, wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL|wxALL, 5);

    wxBoxSizer* itemBoxSizer15 = new wxBoxSizer(wxHORIZONTAL);
    itemFlexGridSizer11->Add(itemBoxSizer15, 0, wxGROW|wxALIGN_CENTER_VERTICAL, 5);

    m_commandCtrl = new wxTextCtrl( itemScrollingDialog1, ID_COMMANDEDITORDIALOG_COMMAND, _T(""), wxDefaultPosition, wxSize(300, -1), 0 );
    m_commandCtrl->SetHelpText(_("The editor or viewer program."));
    if (wxCommandEditorDialog::ShowToolTips())
        m_commandCtrl->SetToolTip(_("The editor or viewer program."));
    itemBoxSizer15->Add(m_commandCtrl, 1, wxALIGN_CENTER_VERTICAL|wxALL, 5);

    wxButton* itemButton17 = new wxButton( itemScrollingDialog1, ID_COMMANDEDITORDIALOG_BROWSE, _("&Browse"), wxDefaultPosition, wxDefaultSize, 0 );
    itemButton17->SetHelpText(_("Click to browse for an application."));
    if (wxCommandEditorDialog::ShowToolTips())
        itemButton17->SetToolTip(_("Click to browse for an application."));
    itemBoxSizer15->Add(itemButton17, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT|wxTOP|wxBOTTOM, 5);

    itemFlexGridSizer11->Add(5, 5, 0, wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL|wxALL, 5);

    wxBoxSizer* itemBoxSizer19 = new wxBoxSizer(wxHORIZONTAL);
    itemFlexGridSizer11->Add(itemBoxSizer19, 0, wxGROW|wxALIGN_CENTER_VERTICAL, 5);

    m_showThisCommandCtrl = new wxCheckBox( itemScrollingDialog1, ID_COMMANDEDITORDIALOG_SHOWTHIS, _("&Show this command"), wxDefaultPosition, wxDefaultSize, 0 );
    m_showThisCommandCtrl->SetValue(false);
    m_showThisCommandCtrl->SetHelpText(_("Check to activate this command."));
    if (wxCommandEditorDialog::ShowToolTips())
        m_showThisCommandCtrl->SetToolTip(_("Check to activate this command."));
    itemBoxSizer19->Add(m_showThisCommandCtrl, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5);

    wxStdDialogButtonSizer* itemStdDialogButtonSizer21 = new wxStdDialogButtonSizer;

    itemBoxSizer3->Add(itemStdDialogButtonSizer21, 0, wxGROW|wxALL, 5);
    wxButton* itemButton22 = new wxButton( itemScrollingDialog1, wxID_OK, _("OK"), wxDefaultPosition, wxDefaultSize, 0 );
    itemButton22->SetDefault();
    itemButton22->SetHelpText(_("Click to confirm your changes."));
    if (wxCommandEditorDialog::ShowToolTips())
        itemButton22->SetToolTip(_("Click to confirm your changes."));
    itemStdDialogButtonSizer21->AddButton(itemButton22);

    wxButton* itemButton23 = new wxButton( itemScrollingDialog1, wxID_CANCEL, _("Cancel"), wxDefaultPosition, wxDefaultSize, 0 );
    itemButton23->SetHelpText(_("Click to cancel your changes."));
    if (wxCommandEditorDialog::ShowToolTips())
        itemButton23->SetToolTip(_("Click to cancel your changes."));
    itemStdDialogButtonSizer21->AddButton(itemButton23);

    wxButton* itemButton24 = new wxButton( itemScrollingDialog1, wxID_HELP, _("&Help"), wxDefaultPosition, wxDefaultSize, 0 );
    itemStdDialogButtonSizer21->AddButton(itemButton24);

    itemStdDialogButtonSizer21->Realize();

////@end wxCommandEditorDialog content construction

    m_captionCtrl->SetLabel(m_caption);

    PopulateCommands();
}


/*
 * Should we show tooltips?
 */

bool wxCommandEditorDialog::ShowToolTips()
{
    if (sm_uiCustomization)
        return sm_uiCustomization->UseToolTips();
    else
        return sm_useTooltips;
}

/*
 * Get bitmap resources
 */

wxBitmap wxCommandEditorDialog::GetBitmapResource( const wxString& name )
{
    // Bitmap retrieval
////@begin wxCommandEditorDialog bitmap retrieval
    wxUnusedVar(name);
    return wxNullBitmap;
////@end wxCommandEditorDialog bitmap retrieval
}

/*
 * Get icon resources
 */

wxIcon wxCommandEditorDialog::GetIconResource( const wxString& name )
{
    // Icon retrieval
////@begin wxCommandEditorDialog icon retrieval
    wxUnusedVar(name);
    return wxNullIcon;
////@end wxCommandEditorDialog icon retrieval
}

/// Populate command list
void wxCommandEditorDialog::PopulateCommands()
{
    ShowCommand(-1);

    m_commandsCtrl->Clear();
    size_t i;
    for (i = 0; i < m_commands.GetCount(); i++)
    {
        const wxEditorCommand& cmd = m_commands[i];
        m_commandsCtrl->Append(cmd.m_title);
    }
    if (m_commandsCtrl->GetCount() > 0)
    {
        m_commandsCtrl->SetSelection(0);
        ShowCommand(0);
    }
}

/// Show command
void wxCommandEditorDialog::ShowCommand(int i)
{
    if (m_nameCtrl->GetValidator())
        m_nameCtrl->GetValidator()->TransferFromWindow();
    if (m_commandCtrl->GetValidator())
        m_commandCtrl->GetValidator()->TransferFromWindow();
    if (m_showThisCommandCtrl->GetValidator())
        m_showThisCommandCtrl->GetValidator()->TransferFromWindow();
    
    if (i == -1)
    {
        m_nameCtrl->SetValidator(wxDefaultValidator);
        m_nameCtrl->SetValue(wxEmptyString);

        m_commandCtrl->SetValidator(wxDefaultValidator);
        m_commandCtrl->SetValue(wxEmptyString);

        m_showThisCommandCtrl->SetValidator(wxDefaultValidator);
        m_showThisCommandCtrl->SetValue(false);
    }
    else
    {
        wxEditorCommand& cmd = m_commands[i];

        m_nameCtrl->SetValidator(wxGenericValidator(& cmd.m_title));
        m_commandCtrl->SetValidator(wxGenericValidator(& cmd.m_command));
        m_showThisCommandCtrl->SetValidator(wxGenericValidator(& cmd.m_enabled));

        m_nameCtrl->GetValidator()->TransferToWindow();
        m_commandCtrl->GetValidator()->TransferToWindow();
        m_showThisCommandCtrl->GetValidator()->TransferToWindow();
    }
}


/*
 * wxEVT_COMMAND_LISTBOX_SELECTED event handler for ID_COMMANDEDITORDIALOG_COMMANDS
 */

void wxCommandEditorDialog::OnCommandeditordialogCommandsSelected( wxCommandEvent& event )
{
    ShowCommand(event.GetSelection());
}


/*
 * wxEVT_COMMAND_BUTTON_CLICKED event handler for ID_COMMANDEDITORDIALOG_ADD
 */

void wxCommandEditorDialog::OnCommandeditordialogAddClick( wxCommandEvent& WXUNUSED(event) )
{
    wxString cmdName = wxGetTextFromUser(_("Please enter a new command name"), _("New Command"),
        wxEmptyString, this);
    if (!cmdName.IsEmpty())
    {
        if (m_commandsCtrl->FindString(cmdName) != -1)
        {
            wxMessageBox(_("A command with this name already exists. Please choose another name."), _("New Command"),
                wxICON_EXCLAMATION|wxOK, this);
            return;
        }

        ShowCommand(-1);

        wxEditorCommand cmd;
        cmd.m_title = cmdName;

        m_commands.Add(cmd);
        m_commandsCtrl->Append(cmdName);

        m_commandsCtrl->SetSelection(m_commands.GetCount()-1);
        ShowCommand(m_commands.GetCount()-1);
    }
}

/*
 * wxEVT_COMMAND_BUTTON_CLICKED event handler for ID_COMMANDEDITORDIALOG_DELETE
 */

void wxCommandEditorDialog::OnCommandeditordialogDeleteClick( wxCommandEvent& WXUNUSED(event) )
{
    int sel = m_commandsCtrl->GetSelection();
    if (sel != -1)
    {
        wxString name(m_commandsCtrl->GetString(sel));

        int ans = wxMessageBox(wxString::Format(_("Delete %s?"), name.c_str()), _("Delete Command"), wxICON_QUESTION|wxYES_NO, this);
        if (ans == wxNO)
            return;

        ShowCommand(-1);

        m_commands.RemoveAt(sel);
        m_commandsCtrl->Delete(sel);

        if (m_commandsCtrl->GetCount() > 0)
        {
            m_commandsCtrl->SetSelection(0);
            ShowCommand(0);
        }
    }
}

/*
 * wxEVT_UPDATE_UI event handler for ID_COMMANDEDITORDIALOG_DELETE
 */

void wxCommandEditorDialog::OnCommandeditordialogDeleteUpdate( wxUpdateUIEvent& event )
{
    event.Enable(m_commandsCtrl->GetSelection() != -1 && !GetCommand(m_commandsCtrl->GetSelection()).IsDefault());
}

/*
 * wxEVT_COMMAND_BUTTON_CLICKED event handler for ID_COMMANDEDITORDIALOG_RENAME
 */

void wxCommandEditorDialog::OnCommandeditordialogRenameClick( wxCommandEvent& WXUNUSED(event) )
{
    int sel = m_commandsCtrl->GetSelection();
    if (sel != -1)
    {
        wxEditorCommand& cmd = m_commands[sel];

        wxString cmdName = wxGetTextFromUser(_("Please enter a new command name"), _("Rename Command"),
            cmd.m_title, this);
        if (!cmdName.IsEmpty() && cmdName != cmd.m_title)
        {
            if (m_commandsCtrl->FindString(cmdName) != -1)
            {
                wxMessageBox(_("A command with this name already exists. Please choose another name."), _("New Command"),
                    wxICON_EXCLAMATION|wxOK, this);
                return;
            }
        }

        m_commandsCtrl->SetString(sel, cmdName);
        m_nameCtrl->SetValue(cmdName);
        m_commands[sel].m_title = cmdName;
    }
}
    
/*
 * wxEVT_UPDATE_UI event handler for ID_COMMANDEDITORDIALOG_RENAME
 */

void wxCommandEditorDialog::OnCommandeditordialogRenameUpdate( wxUpdateUIEvent& event )
{
    event.Enable(m_commandsCtrl->GetSelection() != -1 && !GetCommand(m_commandsCtrl->GetSelection()).IsDefault());
}


/*
 * wxEVT_UPDATE_UI event handler for ID_COMMANDEDITORDIALOG_NAME
 */

void wxCommandEditorDialog::OnCommandeditordialogNameUpdate( wxUpdateUIEvent& event )
{
    event.Enable(m_commandsCtrl->GetSelection() != -1 && !GetCommand(m_commandsCtrl->GetSelection()).IsDefault());
}


/*
 * wxEVT_UPDATE_UI event handler for ID_COMMANDEDITORDIALOG_COMMAND
 */

void wxCommandEditorDialog::OnCommandeditordialogCommandUpdate( wxUpdateUIEvent& event )
{
    event.Enable(m_commandsCtrl->GetSelection() != -1 && !GetCommand(m_commandsCtrl->GetSelection()).IsDefault());
}


/*
 * wxEVT_UPDATE_UI event handler for ID_COMMANDEDITORDIALOG_SHOWTHIS
 */

void wxCommandEditorDialog::OnCommandeditordialogShowthisUpdate( wxUpdateUIEvent& event )
{
    event.Enable(m_commandsCtrl->GetSelection() != -1);
}


/*
 * wxEVT_UPDATE_UI event handler for ID_BUTTON3
 */

void wxCommandEditorDialog::OnCommandeditordialogBrowseUpdate( wxUpdateUIEvent& event )
{
    event.Enable(m_commandsCtrl->GetSelection() != -1 && !GetCommand(m_commandsCtrl->GetSelection()).IsDefault());
}


/*
 * wxEVT_COMMAND_BUTTON_CLICKED event handler for ID_COMMANDEDITORDIALOG_BROWSE
 */

void wxCommandEditorDialog::OnCommandeditordialogBrowseClick( wxCommandEvent& WXUNUSED(event) )
{
#ifdef __WXMSW__
    wxString filter = wxT("Program files (*.exe)|*.exe|All Files (*.*)|*.*");
#else
    wxString filter = wxT("All Files (*.*)|*.*");
#endif

    wxString cmd = m_commandCtrl->GetValue();

    wxFileDialog dialog(this, _("Choose a command"), wxPathOnly(cmd), wxFileNameFromPath(cmd),
        filter, wxFD_OPEN);
    
    if (dialog.ShowModal() == wxID_OK)
    {
        cmd = dialog.GetPath();
        m_commandCtrl->SetValue(cmd);
    }
}


/*
 * wxEVT_COMMAND_BUTTON_CLICKED event handler for wxID_HELP
 */

void wxCommandEditorDialog::OnHelpClick( wxCommandEvent& WXUNUSED(event) )
{
    if (sm_uiCustomization)
        sm_uiCustomization->ShowHelp(sm_helpId, this);
}


/*
 * wxEVT_UPDATE_UI event handler for wxID_HELP
 */

void wxCommandEditorDialog::OnHelpUpdate( wxUpdateUIEvent& event )
{
    event.Enable(sm_helpId != 0);
}

